import React from "react";
import {
    PlusOutlined,
    DollarOutlined,
    UserOutlined,
    FieldNumberOutlined,
    CalendarOutlined,
    ClockCircleOutlined,
    FileSearchOutlined,
} from '@ant-design/icons';
import { Divider, Spin, Row, Col, Card, List, Upload, Form, Button, message, Timeline, Table } from 'antd';
import { v4 as uuidv4 } from 'uuid';
import moment from 'moment';

import hub from '../../utilities/hub';
import CONSTANT from '../../utilities/constant';
import TimerProgress from "./timerProgress";

class AMDashboard extends React.Component {
    formRef = React.createRef();

    constructor(props) {
        super(props);
        this.state = { loading: false, handingLog: [] };
        this.uploadProps = {
            beforeUpload: () => false,
            // onPreview: this.handlePreview,
            maxCount: 1,
            listType: "picture-card"
        };

        this.formItemLayout = {
            labelCol: { span: 6 },
            wrapperCol: { span: 14 },
        };

        this.fileList = [];
    }

    submitContract = async (values) => {
        let ws;

        try {
            this.setState({ loading: true, handingLog: [] });
            values['createtime'] = new Date().getTime() + "";
            delete values.image;
            console.log('Received values of form: ', values, this.fileList);

            const clientId = uuidv4().replace(/-/g, '');
            values['clientId'] = clientId;

            // add create websocket connection here
            ws = new WebSocket(`${CONSTANT.WEB_SERVER_WS_URL}/${CONSTANT.VERSION}${CONSTANT.WS_PROCESS}/${clientId}`);

            ws.onopen = () => {
                console.log("WebSocket connected");
            };

            ws.onmessage = (event) => {
                console.log("Progress update:", event.data);
                const wsinfo = JSON.parse(event.data);
                let waitingTime = 1;
                if (wsinfo.estimateTimeSpend) {
                    waitingTime = Math.max(wsinfo.estimateTimeSpend, 300);
                }
                // 可以在这里更新 UI 进度条或其他反馈
                const { handingLog, loading } = this.state;
                handingLog.reverse();

                if (handingLog.length > 0) {
                    handingLog[handingLog.length - 1].dot = (
                        <ClockCircleOutlined style={{ fontSize: '12px' }} />
                    );

                    handingLog[handingLog.length - 1].children = (
                        <TimerProgress waitingTime={waitingTime} interval={0} content={handingLog[handingLog.length - 1].content} />
                    )
                }

                handingLog.push({
                    label: moment().format('YYYY-MM-DD HH:mm:ss.SSS'),
                    dot: (
                        loading ?
                            <Spin /> :
                            <ClockCircleOutlined style={{ fontSize: '12px' }} />
                    ),
                    children: (
                        <TimerProgress waitingTime={waitingTime} interval={loading ? 1 : 0} content={`${handingLog.length + 1} - ${wsinfo.content}`} />
                    ),
                    content: `${handingLog.length + 1} - ${wsinfo.content}`
                });

                handingLog.reverse();

                this.setState({ handingLog });
            };

            ws.onclose = () => {
                console.log("WebSocket connection closed");
            };

            ws.onerror = (error) => {
                console.error("WebSocket error:", error);
            };

            const resp = await hub.uploadContract(values, this.fileList);
            const contract_info = this.assemble(resp);

            this.setState({ loading: false, contract_info });

        } catch (error) {
            // message.error('解析合同出错，请联系管理员。');
            console.log('parse contract error: ', error);
            this.setState({
                loading: false, contract_info: {
                    title: 'content parse failed'
                },
                handingLog: [error]
            });
        } finally {
            setTimeout(() => {
                if (ws && ws.readyState === WebSocket.OPEN) {
                    ws.close();
                }
            }, 5000);
        }
    };

    assemble = (resp) => {
        console.log('assemble resp: ', resp);
        const { data } = resp.contract_info;
        const amount = this.formatAmount(data.contract_amount);

        return {
            title: data.contract_name,
            detail: [
                {
                    title: 'Contract ID',
                    value: data.contract_id ? data.contract_id : 'not found',
                    avatar: <FieldNumberOutlined />
                },
                {
                    title: 'Buyer',
                    value: data.party_a ? data.party_a : 'not found',
                    avatar: <UserOutlined />
                },
                {
                    title: 'Supplier',
                    value: data.party_b ? data.party_b : 'not found',
                    avatar: <UserOutlined />
                },
                {
                    title: 'Contract start date',
                    value: data.signing_date ? data.signing_date : 'not found',
                    avatar: <CalendarOutlined />
                },
                {
                    title: 'Amount（K USD）',
                    value: amount,
                    avatar: <DollarOutlined />
                },
                {
                    title: 'Payment milestone',
                    value: (data.milestone ?
                        <Table bordered dataSource={data.milestone.dataSource} columns={data.milestone.columns} />
                        : 'not found'),
                    avatar: <FileSearchOutlined />
                }
            ]
        }
    }

    formatAmount = (amount) => {
        if(amount === undefined || amount === null) {
            return 'not found';
        }

        const number = Number(amount);

        if (isNaN(number)) {
            return amount; 
        }

        return number.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 });

    }

    normFile = (e) => {
        console.log('Upload event:', e);
        this.fileList = e.fileList;
        return e && e.fileList;
    };

    parseContractInfo = (loading, contract_info) => {
        if (!loading && contract_info) {
            return (
                <Card
                    title={contract_info.title}
                    bordered={false}
                >
                    <List
                        itemLayout="horizontal"
                        dataSource={contract_info.detail}
                        renderItem={(item, index) => (
                            <List.Item>
                                <List.Item.Meta
                                    avatar={item.avatar}
                                    title={item.title}
                                    description={item.value}
                                />
                            </List.Item>
                        )}
                    />
                </Card>
            );
        } else if (loading) {
            return (
                <Card title={<Spin />} bordered={false} >
                    <Spin />
                </Card>
            );
        }

        return (
            <Card
                title="no contract"
                bordered={false}
            ></Card>
        );
    }

    showSubmit = () => {
        message.success('Results saved to server successfully', 10);

        // const content = `` +
        //     `Wikis are powered by wiki software, also known as wiki engines. Being a form of content management system, ` +
        //     `these differ from other web-based systems such as blog software or static site generators in that the content ` +
        //     `is created without any defined owner or leader. Wikis have little inherent structure, allowing one to emerge ` +
        //     `according to the needs of the users.[1] Wiki engines usually allow content to be written using a lightweight ` +
        //     `markup language and sometimes edited with the help of a rich-text editor.[2] There are dozens of different wiki ` +
        //     `engines in use, both standalone and part of other software, such as bug tracking systems. Some wiki engines ` +
        //     `are free and open-source, whereas others are proprietary. Some permit control over different functions (levels of access); ` +
        //     `for example, editing rights may permit changing, adding, or removing material. Others may permit access without enforcing ` +
        //     `access control. Further rules may be imposed to organize content. In addition to hosting user-authored content, ` +
        //     `wikis allow those users to interact, hold discussions, and collaborate.[3]` +
        //     `There are hundreds of thousands of wikis in use, both public and private, including wikis functioning as ` +
        //     `knowledge management resources, note-taking tools, community websites, and intranets. Ward Cunningham, ` +
        //     `the developer of the first wiki software, WikiWikiWeb, originally described wiki as "the simplest online ` +
        //     `database that could possibly work".[4] "Wiki" (pronounced [wiki][note 1]) is a Hawaiian word meaning "quick".[5][6][7]` +
        //     `The online encyclopedia project Wikipedia is the most popular wiki-based website, as well being one of the internet's ` +
        //     `most popular websites, having been ranked consistently as such since at least 2007.[8] Wikipedia is not a single wiki but ` +
        //     `rather a collection of hundreds of wikis, with each one pertaining to a specific language. The English-language Wikipedia has ` +
        //     `the largest collection of articles, standing at 6,966,483 as of March 2025.[9]`;

        // this.setState({
        //     page: (
        //         <TimerProgress waitingTime={0} interval={0} content={`1 - ${content}`} />
        //     )
        // });

    }

    renderPage = () => {
        const { loading, contract_info, handingLog } = this.state;
        // console.log(contract_info);
        const info = this.parseContractInfo(loading, contract_info);

        return (
            <div>
                <h2>Contract Management</h2>
                <Divider />

                <Row gutter={16}>
                    <Col span={8} >
                        <Card title="Upload Contract" bordered={false}>
                            {loading ? <Spin /> :
                                <Form
                                    ref={this.formRef}
                                    name="validate_other"
                                    {...this.formItemLayout}
                                    onFinish={this.submitContract}
                                >
                                    <Form.Item name="image" valuePropName="fileList" getValueFromEvent={this.normFile} noStyle>
                                        <Upload {...this.uploadProps}>
                                            <PlusOutlined />
                                            <div style={{ marginTop: 8 }}>Choose file</div>
                                        </Upload>
                                    </Form.Item>

                                    <Divider />

                                    <Form.Item wrapperCol={{ span: 24, offset: 2 }}>
                                        <Button htmlType="submit" style={{ marginRight: '25px' }}>Upload</Button>
                                        <Button onClick={this.showSubmit}>Submit</Button>
                                    </Form.Item>
                                </Form>}
                        </Card>

                    </Col>
                    <Col span={16}>
                        {info}
                    </Col>
                </Row>

                {/* {loading ? */}
                <Row gutter={16}>
                    <Col span={18}>
                        <Timeline
                            mode="left"
                            style={{ marginTop: '40px' }}
                            items={handingLog}
                        />
                    </Col>
                </Row>
                {/* : null} */}
            </div >
        )

    }

    render() {
        // let { page } = this.state;

        // if (!page) {
        //     page = this.renderPage();
        // }
        const page = this.renderPage();

        return (
            <div>
                {page}
            </div>
        );
    }

}

export default AMDashboard;
